package dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//这是一个代理类的调用处理程序
public class MyInvocationHandler1 implements InvocationHandler {

    //获取业务接口
    Opration opration;

    //通过set方法就能动态指定实现类
    public void setOpration(Opration opration) {
        this.opration = opration;
    }

    //生成代理一类业务的代理类
    public Opration getProxy() {
        //使用本类的加载器是因为都是应用类加载器，使用this可以提高在开发不同业务时代码的复用度，    
        //如果使用业务接口来写那么不同的业务就需要修改接口名

        //然后就是通过反射的方式获取业务的接口 

        //最后是需要一个调用处理程序，也就是需要一个InvocationHandler的实例,而这个类就是一个实                                                                                
        //例，所以是this
        return (Opration) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                opration.getClass().getInterfaces(), this);
    }

    //本调用处理程序只有实现invoke方法才能让代理类根据不同的实现类实现业务
    //当代理类调用方法时，会自动将代理类、所调用的方法以及参数交给invoke，利用反射实现方法调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //这里需要传入的是已经指定实现类的业务接口实例，以及参数
        //所以这就相当于去找指定实现类的方法，并将参数传入来调用这个方法，最后返回值
        //不同方法的返回值类型不同，Object万类之父就能兼容各种类型，最后强制转换类型即可
        Object result = method.invoke(opration, args);
        return result;
    }
}